/**
 * Copyright (C) 2014
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package psn.shan.xml.enhancedvalidator.rules;

import java.util.Collection;
import java.util.List;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
import org.jdom2.xpath.XPathBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;

import psn.shan.xml.enhancedvalidator.rules.comparator.AbstractComparator;

/**
 * AbstractBaseRule
 * Base class for rules 
 * 
 * @author Shan
 * 
 */
@Accessors(prefix = "m")
@EqualsAndHashCode
@ToString(includeFieldNames=true)
public abstract class AbstractBaseRule {
	@Getter @Setter
	private String mName = null;
	
	@Getter
	protected static RuleType mRuleType = null;
	
	@Getter @Setter
	private String mValidates = null;
	
	@Getter @Setter
	private String mAccessor = null;
	
	@Getter @Setter
	private List<String> mAttributes = null;
	
	@Getter @Setter	
	private String mException = null;
	
	@Getter @Setter	
	private AbstractComparator<?> mComparator = null;
	
	protected XPathExpression<Element> mXPath = null;
	
	protected static String VALUE_VARIABLE = "$Value$";

	public abstract List<String> applyRule(Document aInput);
	
	protected List<Element> getRuledSubjects(Document aInput) {
		return mXPath.evaluate(aInput);
	}
	
	public void setupRule(Collection<Namespace> aRuleverse) {
		XPathBuilder<Element> lXPathBuilder = new XPathBuilder<Element>(mValidates, Filters.element());
		lXPathBuilder.setNamespaces(aRuleverse);
		
		XPathFactory lXPathFactory = XPathFactory.instance();
		
		mXPath = lXPathBuilder.compileWith(lXPathFactory);
	}
}
